#include <boost/spirit/include/classic_core.hpp>
#include <boost/spirit/include/classic_push_back_actor.hpp>
#include <iostream>
#include <vector>
#include <string>
#include <fstream>

using namespace std;
using namespace boost::spirit::classic;

std::string get_config_spec(){
    ifstream ifs("cfg_CI_BF_B5");
    if (!ifs){
        cerr << "Can't open the file cfg_CI_BF_B5" << endl;
        exit(1);
    }
    string line, total;
    while(getline(ifs, line)){
        line += "\n";
        total += line;
    }
    return total;
}

void print_version(char const* first, char const* last)
{
    string version(first, last);
    cout << "The version is: " << version << std::endl;
}

void get_product(char const* first, char const* last)
{
    string product(first, last);
    cout << "The product is: " << product << std::endl;
}

void print_sc_name(const char* first, const char* last)
{
    string sc_name(first, last);
    cout << "The SC name is: " << sc_name << endl;
}

void print_sc_path(const char* first, const char* last)
{
    string sc_path(first, last);
    cout << "The SC version is: " << sc_path << endl;
}

void print_shared_baselines(const char* first, const char* last)
{
    cout << "SCs from shared: " << endl;
}

void print_dimension_baselines(const char* first, const char* last)
{
    cout << "SCs from dimensions: " << endl;
}


int main(){
    //config_spec grammer describtion
    rule<> version = str_p("version") >> +blank_p >> (*graph_p)[&print_version] >> +space_p;
    rule<> product = str_p("product") >> +blank_p >> (*graph_p)[&get_product] >> +space_p;

    rule<> sc_info = (* (graph_p&(~str_p('<'))));
    
    rule<> sc_list = *(sc_info[&print_sc_name] >> +blank_p >> sc_info[&print_sc_path] >> +space_p);
    
    rule<> shared_baselines = str_p("<baselines from share>")[&print_shared_baselines] >> +space_p >> sc_list >> str_p("</baselines>") >> +space_p ;
    rule<> dimension_baselines = str_p("<baselines from dimensions>")[&print_dimension_baselines] >> +space_p >> sc_list >> str_p("</baselines>") >> +space_p;
    rule<> config_spec_parser = version >> product >>
        shared_baselines >> dimension_baselines >>
        end_p;
    
    
    //parse the cofnig_spec
    cout << "Input: " << endl;
    cout << get_config_spec();
    cout << "Input ended." << endl << endl;
    
    if (parse(get_config_spec().c_str(), config_spec_parser).full){
        cout << "Success" << endl;
    }
    else{
        cout << "Fail" << endl;
    }
    return 0;
}

                

// struct config : public grammer<calculator>
// {
//     template <typename ScannerT>
//     struct definition
//     {
//         definition(const config& self)
//         {
//         }
//         rule<ScannerT> from_share, from_dimension, config_spec;
//         rule<ScannerT> const& start(){
//             const(return config_spec);
//         }
//     };
// };
